package com.xifly.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.xifly.utils.ResultMsg;
import com.xifly.utils.ResultStatusCode;
import sun.misc.BASE64Decoder;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class HTTPBasicAuthorizeAttribute implements Filter {
    private static String Name = "test";
    private static String Password = "test";

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        ResultStatusCode resultStatusCode = checkHTTPBasicAuthorize(servletRequest);
        if (resultStatusCode != ResultStatusCode.OK){
            HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
            httpServletResponse.setCharacterEncoding("UTF-8");
            httpServletResponse.setContentType("application/json; charset=utf-8");
            httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);

            ObjectMapper mapper = new ObjectMapper();

            ResultMsg resultMsg = new ResultMsg(ResultStatusCode.PERMISSION_DENIED.getErrorcode(),ResultStatusCode.PERMISSION_DENIED.getErrormsg(),null);
            httpServletResponse.getWriter().write(mapper.writeValueAsString(resultMsg));
            return;
        } else {
            filterChain.doFilter(servletRequest,servletResponse);
        }
    }

    @Override
    public void destroy() { }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException { }

    private ResultStatusCode checkHTTPBasicAuthorize(ServletRequest request){
        try {
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            String auth = httpServletRequest.getHeader("Authorization");
            if ((auth != null) && (auth.length() > 6)) {
                String headString = auth.substring(0, 5).toLowerCase();
                if (headString.compareTo("basic") == 0) {
                    auth = auth.substring(6, auth.length());
                    String decodedAuth = getFromBASE64(auth);
                    if (decodedAuth != null) {
                        String[] userArray = decodedAuth.split(":");
                        if (userArray != null && userArray.length == 2) {
                            if (userArray[0].compareTo(Name) == 0 && userArray[1].compareTo(Password) == 0) {
                                return ResultStatusCode.OK;
                            }
                        }
                    }
                }
            }
            return ResultStatusCode.PERMISSION_DENIED;
        } catch (Exception e){
            return ResultStatusCode.PERMISSION_DENIED;
        }
    }

    private String getFromBASE64(String s){
        if (s == null)
            return null;

        BASE64Decoder decoder = new BASE64Decoder();
        try {
            byte[] b = decoder.decodeBuffer(s);
            return new String(b);
        } catch (Exception e) {
                return null;
        }
    }
}
